package com.seed.bpmn.provider.camunda.common.util;

import com.seed.bpmn.engine.common.constants.BpmnConstants;
import com.seed.bpmn.engine.common.util.Empty;
import com.seed.bpmn.engine.dto.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.time.DateFormatUtils;
import org.camunda.bpm.engine.history.HistoricProcessInstance;
import org.camunda.bpm.engine.history.HistoricTaskInstance;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Comment;
import org.camunda.bpm.engine.task.IdentityLink;
import org.camunda.bpm.engine.task.Task;

import java.util.*;

public class DTOUtil {

    public static ProcessDefinitionDTO getProcessDefinitionDTO(ProcessDefinition d){
        ProcessDefinitionDTO dto = null;
        if(Empty.isNotEmpty(d)){
            dto = new ProcessDefinitionDTO();
            dto.setId(d.getId());
            dto.setCategory(d.getCategory());
            dto.setKey(d.getKey());
            dto.setName(d.getName());
            dto.setVersion(d.getVersion());
            dto.setDeploymentId(d.getDeploymentId());
        }
        return dto;
    }

    public static ProcessInstanceDTO getProcessInstanceDTO(HistoricProcessInstance hpi){
        ProcessInstanceDTO dto = null;
        if(Empty.isNotEmpty(hpi)){
            dto = new ProcessInstanceDTO();
            dto.setId(hpi.getId());
            dto.setBusinessKey(hpi.getBusinessKey());
            dto.setProcessDefinitionId(hpi.getProcessDefinitionId());
            dto.setStartTime(formatDate(hpi.getStartTime()));
            dto.setEndTime(formatDate(hpi.getEndTime()));
        }
        return dto;
    }

    public static ProcessInstanceDTO getProcessInstanceDTO(ProcessInstance pi){
        ProcessInstanceDTO dto = null;
        if(Empty.isNotEmpty(pi)){
            dto = new ProcessInstanceDTO();
            dto.setId(pi.getId());
            dto.setBusinessKey(pi.getBusinessKey());
            dto.setStartTime(formatDate(new Date()));
            dto.setProcessDefinitionId(pi.getProcessDefinitionId());
        }
        return dto;
    }

    public static TaskDTO getTaskDTO(Task t){
        TaskDTO dto = null;
        if(Empty.isNotEmpty(t)){
            dto = new TaskDTO();
            dto.setId(t.getId());
            dto.setName(t.getName());
            dto.setKey(t.getTaskDefinitionKey());
            dto.setProcessInstanceId(t.getProcessInstanceId());
            dto.setProcessDefinitionId(t.getProcessDefinitionId());
            dto.setExecutionId(t.getExecutionId());
            dto.setAssignee(t.getAssignee());
            dto.setStartTime(formatDate(t.getCreateTime()));
            dto.setParentTaskId(t.getParentTaskId());
        }
        return dto;
    }

    public static TaskDTO getTaskDTO(HistoricTaskInstance t){
        TaskDTO dto = null;
        if(Empty.isNotEmpty(t)){
            dto = new TaskDTO();
            dto.setId(t.getId());
            dto.setName(t.getName());
            dto.setKey(t.getTaskDefinitionKey());
            dto.setProcessInstanceId(t.getProcessInstanceId());
            dto.setProcessDefinitionId(t.getProcessDefinitionId());
            dto.setExecutionId(t.getExecutionId());
            dto.setAssignee(t.getAssignee());
            dto.setStartTime(formatDate(t.getStartTime()));
            dto.setEndTime(formatDate(t.getEndTime()));
            dto.setParentTaskId(t.getParentTaskId());
        }
        return dto;
    }

    public static CommentDTO getCommentDTO(Comment c){
        CommentDTO dto = null;
        if(Empty.isNotEmpty(c)){
            dto = new CommentDTO();
            dto.setId(c.getId());
            dto.setUserId(c.getUserId());
            dto.setTime(formatDate(c.getTime()));
            dto.setTaskId(c.getTaskId());
            dto.setProcessInstanceId(c.getProcessInstanceId());
            dto.setFullMessage(c.getFullMessage());
        }
        return dto;
    }

    public static TaskEntityDTO getTaskEntityDTO(Task t, List<IdentityLinkDTO> identityLinks){
        TaskEntityDTO dto = null;
        if(Empty.isNotEmpty(t)){
            dto = new TaskEntityDTO();
            dto.setId(t.getId());
            dto.setName(t.getName());
            dto.setKey(t.getTaskDefinitionKey());
            dto.setProcessInstanceId(t.getProcessInstanceId());
            dto.setProcessDefinitionId(t.getProcessDefinitionId());
            dto.setExecutionId(t.getExecutionId());
            dto.setAssignee(t.getAssignee());
            dto.setStartTime(formatDate(t.getCreateTime()));
            dto.setParentTaskId(t.getParentTaskId());
            dto.setIdentityLinks(Empty.isEmpty(identityLinks) ? new ArrayList<IdentityLinkDTO>() : identityLinks);
        }
        return dto;
    }

    public static IdentityLinkDTO getIdentityLinkDTO(IdentityLink i){
        IdentityLinkDTO dto = null;
        if(Empty.isNotEmpty(i)){
            dto = new IdentityLinkDTO();
            dto.setId(i.getId());
            dto.setUserId(i.getUserId());
            dto.setType(i.getType());
            dto.setTaskId(i.getTaskId());
            dto.setProcessDefId(i.getProcessDefId());
            dto.setGroupId(i.getGroupId());
            dto.setTenantId(i.getTenantId());
        }
        return dto;
    }

    public static String formatDate(Date date){
        return Empty.isEmpty(date) ? "" : DateFormatUtils.format(date,"yyyy-MM-dd HH:mm:ss");
    }

    public static NodeDTO getNodeDTO(JSONObject data, NodeDTO node){
        if(Empty.isNotEmpty(data)){
            //环节类型
            if(data.has(BpmnConstants.ATTRIBUTE_TYPE)){
                node.setType(data.getString(BpmnConstants.ATTRIBUTE_TYPE));
            }

            //是否需填写处理意见
            if(data.has(BpmnConstants.ATTRIBUTE_ADVICE)){
                node.setAdvice(data.getString(BpmnConstants.ATTRIBUTE_ADVICE));
            }

            //流程环节配置用户组信息
            if(data.has(BpmnConstants.ATTRIBUTE_TASK_USER_CANDIDATEGROUPS)){
                node.setGroups(data.getString(BpmnConstants.ATTRIBUTE_TASK_USER_CANDIDATEGROUPS));
            }

            //流程环节office操作配置
            if(data.has(BpmnConstants.ATTRIBUTE_OFFICE)){
                JSONArray office = data.getJSONArray(BpmnConstants.ATTRIBUTE_OFFICE);
                node.setOffice(arrayToMap(office));
            }

            //流程环节controlCode配置
            if(data.has(BpmnConstants.ATTRIBUTE_CONTROL_CODE)){
                JSONArray controlCode = data.getJSONArray(BpmnConstants.ATTRIBUTE_CONTROL_CODE);
                node.setControlCode(arrayToMap(controlCode));
            }
        }
        return node;
    }

    /** 数组转Map */
    public static Map<String,Boolean> arrayToMap(JSONArray data){
        Map<String,Boolean> map = new HashMap<String,Boolean>();
        for(Object o : data){
            if(Empty.isNotEmpty(o)){
                map.put(o.toString(),true);
            }
        }
       return map;
    }
}
